package com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_heart

import android.hardware.Camera
import android.os.CountDownTimer
import android.view.View
import androidx.databinding.ObservableField
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.liveData
import androidx.lifecycle.switchMap
import com.bp.hearthealth.pulse.lnapps.R
import com.bp.hearthealth.pulse.lnapps.ads.model.AdsSwitch
import com.bp.hearthealth.pulse.lnapps.bp_db.bp_heartrate.BpHeartRateBean
import com.bp.hearthealth.pulse.lnapps.bp_utils.Constants
import com.bp.hearthealth.pulse.lnapps.base.BpBaseViewModel
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_heart.bp_detect.BpImageProcessing
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.LinkedList
import java.util.concurrent.atomic.AtomicBoolean

class BpHeartRateViewModel(private val repository: BpHeartRateRepository) : BpBaseViewModel() {

    /*    ===============================================心率============================================*/
    private val processing = AtomicBoolean(false)
    private var averageIndex = 0
    internal var averageSize = 0
    private val averageArraySize = 4
    private val averageArray = IntArray(averageArraySize)
    private var endTimeH: Long = 0

    enum class TYPE { GREEN, RED }

    //设置默认类型
    private var currentType = TYPE.GREEN

    //心跳下标值
    private var beatsIndex = 0

    //心跳数组的大小
    private val beatsArraySize = 3

    //心跳数组
    private val beatsArray = IntArray(beatsArraySize)
    private var beats = 0.0

    //开始时间
    var startTime: Long = 0
    internal val averageData = LinkedList<Int>()
    val beatsAvgUi = ObservableField("00")
    var resetView = MutableLiveData<Unit>()
    var startHeart = MutableLiveData<Boolean>()
    var averageCode = MutableLiveData<Int>()
    private val viewModelScope = CoroutineScope(Dispatchers.Main + SupervisorJob())

    fun previewCallback(data: ByteArray, cam: Camera) {
        val size = cam.parameters.previewSize ?: throw NullPointerException()
        if (!processing.compareAndSet(false, true)) {
            return
        }
        val width = size.width
        val height = size.height

        //图像处理
        val imgAvg = BpImageProcessing.decodeYUV420SPtoRedAvg(data.clone(), height, width)
        if (imgAvg == 255 || imgAvg < 150) {
            //非检测到，开启倒计时
            endTimeH = 0
            resetView.value = Unit
            processing.set(false)
            return
        }
        //计算平均值
        var averageArrayAvg = 0
        var averageArrayCnt = 0
        for (i in averageArray.indices) {
            if (averageArray[i] > 0) {
                averageArrayAvg += averageArray[i]
                averageArrayCnt++
            }
        }

        val rollingAverage = if (averageArrayCnt > 0) averageArrayAvg / averageArrayCnt else 0
        var newType: TYPE = currentType
        if (imgAvg < rollingAverage) {
            newType = TYPE.RED
            if (newType != currentType) {
                beats++
            }
        } else if (imgAvg > rollingAverage) {
            newType = TYPE.GREEN
        }
        if (averageIndex == averageArraySize) {
            averageIndex = 0
        }
        averageArray[averageIndex] = imgAvg
        averageIndex++
        if (newType != currentType) {
            currentType = newType
        }

        val endTime = System.currentTimeMillis()
        val totalTimeInSecs: Double = (endTime - startTime) / 1000.0
        if (totalTimeInSecs >= 2) {
            val bps: Double = beats / totalTimeInSecs //每秒心跳数
            val dpm = (bps * 60.0).toInt() //每分钟心跳数
            if (dpm < 30 || dpm > 180 || imgAvg < 200) {
                //获取系统开始时间（ms）
                startTime = System.currentTimeMillis()
                //beats心跳总数
                beats = 0.0
                processing.set(false)
                return
            }

            if (beatsIndex == beatsArraySize) {
                beatsIndex = 0
            }
            beatsArray[beatsIndex] = dpm
            beatsIndex++

            var beatsArrayAvg = 0
            var beatsArrayCnt = 0
            for (i in beatsArray.indices) {
                if (beatsArray[i] > 0) {
                    beatsArrayAvg += beatsArray[i]
                    beatsArrayCnt++
                }
            }
            val beatsAvg = beatsArrayAvg / beatsArrayCnt
            averageSize += beatsAvg
            averageCode.value = averageSize
            averageData.add(beatsAvg)
            beatsAvgUi.set(beatsAvg.toString())
            startTime = System.currentTimeMillis()
            beats = 0.0
            if (endTimeH == 0L) {
                startHeart.value = true
                endTimeH = System.currentTimeMillis() + Constants.HEART_RATE_TIME
            }
        }
        processing.set(false)
    }

    /*    ===============================================心率============================================*/

    private var countDownTimer: CountDownTimer? = null
    private val userId = MutableLiveData<String>()
    private val unLockedId = MutableLiveData<Long>()
    val timerDown = MutableLiveData<Boolean>()
    private val updateDetection = MutableLiveData<Int>()
    val showViewToUnlock = ObservableField(false)
    val unLocked = ObservableField(false)
    val updateDate = ObservableField<String>()
    val listSize = MutableLiveData(-1)
    private var deleteId = MutableLiveData<Long>()
    private var inquireBeanId = MutableLiveData<Long>()
    private var insertHeartRate = MutableLiveData<HeartRateRequestParam>()

    fun startHeartRateTimer() {
        countDownTimer = object : CountDownTimer(AdsSwitch.getBpRvCds().toLong() * 1000, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                updateDate.set("${(millisUntilFinished / 1000) + 1}s")
                timerDown.value = false
            }

            override fun onFinish() {
                //播放广告
                timerDown.value = true
                showViewToUnlock.set(true)
            }
        }
        countDownTimer?.start()
    }

    fun stopHeartRateTimer() {
        showViewToUnlock.set(true)
        countDownTimer?.cancel()
    }

    override fun onCleared() {
        super.onCleared()
        countDownTimer?.cancel()
    }

    fun onClick(view: View) {
        when (view.id) {
            R.id.tv_cancel -> {
                showViewToUnlock.set(true)
                countDownTimer?.cancel()
            }
        }
    }

    //第一次打开引导页
    fun updateIsFirstGuide() {
        viewModelScope.launch(Dispatchers.Main) {
            updateDetection.value = repository.updateIsFirstDetection()
        }
    }


    //更新授权
    fun updateAuthorizePermission() {
        viewModelScope.launch(Dispatchers.Main) {
            repository.updateAuthorize()
        }
    }

    /**
     * 保存心率数据
     */
    inner class HeartRateRequestParam(
        val userId: String, val average: Int
    )

    fun insertHeartRateBean(userId: String, endAverage: Int) {
        insertHeartRate.value = HeartRateRequestParam(userId = userId, average = endAverage)
    }

    val insertHeartRateResult = insertHeartRate.switchMap {
        liveData {
            val result = try {
                val list = mutableListOf<BpHeartRateBean>()
                val average = it.average
                list.add(
                    BpHeartRateBean(
                        userId = Constants.USER_ID, number = average, type = if (average < 60) {
                            1
                        } else if (average in 60..100) {
                            2
                        } else {
                            3
                        }, date = System.currentTimeMillis()
                    )
                )
                val heartRate = repository.insertHeartRate(list)
                Result.success(heartRate)
            } catch (e: Exception) {
                Result.failure(e)
            }
            emit(result)
        }
    }

    /**
     * 心率报告页解锁
     */
    fun unlock(id: Long) {
        if (id != -1L) {
            unLockedId.value = id
        }
    }

    val unlockResult = unLockedId.switchMap {
        liveData {
            val result = try {
                val updateUnlocked = repository.updateUnlocked(it)
                Result.success(updateUnlocked)
            } catch (e: Exception) {
                Result.failure(e)
            }
            emit(result)
        }
    }

    /**
     * 心率检测列表
     */
    fun loadHeartRateList(userId: String) {
        this.userId.value = userId
    }

    val heartRateListResult = userId.switchMap {
        liveData {
            val result = try {
                val rateBeanList = repository.loadHeartRateList()
                Result.success(rateBeanList)
            } catch (e: Exception) {
                listSize.value = 0
                Result.failure(e)
            }
            emit(result)
        }
    }

    /**
     * 删除指定id心率数据
     */
    fun delete(id: Long) {
        if (id != -1L) {
            deleteId.value = id
        }
    }

    val deleteResult = deleteId.switchMap {
        liveData {
            val result = try {
                val code = repository.deleteHeartRateById(it)
                Result.success(code)
            } catch (e: Exception) {
                Result.failure(e)
            }
            emit(result)
        }
    }

    /**
     * 查询指定id心率数据对象
     */
    fun inquireBean(id: Long) {
        if (id != -1L) {
            inquireBeanId.value = id
        }
    }

    val inquireBeanResult = inquireBeanId.switchMap {
        liveData {
            val result = try {
                val code = repository.getHeartRateBeanById(it)
                Result.success(code)
            } catch (e: Exception) {
                Result.failure(e)
            }
            emit(result)
        }
    }
}